/*
 * @Author: Dorange.Wang
 * @Date: 2021-04-07 15:50:47
 * @LastEditors: wangming
 * @LastEditTime: 2022-03-02 18:28:47
 * @Description: file content
 */
import lodash from 'lodash'
import moment from 'moment'
import { Message } from 'element-ui'
import store from '@/store'

/**
 * list转tree
 * 默认父节点parentId，子节点children，根节点0
 * @param {*} list
 * @param {*} parentId
 * @returns
 */
export function arrayToTree(list, parentId = 0, parentIds = []) {
  return list
    .filter((item) => item.parentId === parentId)
    .map((item, index, arr) => {
      const pids = parentId ? [...parentIds, parentId] : [...parentIds]
      return {
        ...item,
        _isFirst: index === 0,
        _isLast: index === arr.length - 1,
        _parentIds: pids,
        children: arrayToTree(list, item.id, pids)
      }
    })
}

/**
 * tree转list
 * @param {*} tree
 * @param {*} list
 * @returns
 */
export function treeToArray(tree, list = []) {
  lodash.cloneDeep(tree).forEach((node) => {
    const { children } = node
    if (children) {
      delete node.children

      if (children.length) {
        list.push(node)
        return treeToArray(children, list)
      }
    }
    list.push(node)
  })
  return list
}

/**
 * 增加树节点属性
 * _isFirst 当前分组第一个
 * _isLast 当前分组最后一个
 * _parentIds 父节点数组
 * @param {*} tree
 * @param {*} parentIds
 * @returns
 */
export function treeToTree(tree, parentIds = []) {
  return tree.map((item, index, arr) => {
    const pids = item.parentId ? [...parentIds, item.parentId] : [...parentIds]
    return {
      ...item,
      _isFirst: index === 0,
      _isLast: index === arr.length - 1,
      _parentIds: pids,
      children: treeToTree(item.children, pids)
    }
  })
}

export function randomString(len = 32) {
  const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  /** **默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
  const maxPos = chars.length
  let str = ''
  for (let i = 0; i < len; i++) {
    str += chars.charAt(Math.floor(Math.random() * maxPos))
  }
  return str
}
export function randomStringStrong(){
  const charsA = 'ABCDEFGHJKMNPQRSTWXYZ'
  const charsa = 'abcdefhijkmnprstwxyz'
  const charsnum = '0123456789'
  const charsymbol = '~!@#$%^&*()_+-='
  return charsA.charAt(Math.floor(Math.random() * (charsA.length)))+charsA.charAt(Math.floor(Math.random() * (charsA.length)))+
  charsa.charAt(Math.floor(Math.random() * (charsa.length)))+charsa.charAt(Math.floor(Math.random() * (charsa.length)))+
  charsnum.charAt(Math.floor(Math.random() * (charsnum.length)))+charsymbol.charAt(Math.floor(Math.random() * (charsymbol.length)))
}
export function closeWindow() {
  if (navigator.userAgent.indexOf('MSIE') > 0) {
    // close IE
    if (navigator.userAgent.indexOf('MSIE 6.0') > 0) {
      window.opener = null
      window.close()
    } else {
      window.open('', '_top')
      window.top.close()
    }
  } else {
    // close chrome;It is effective when it is only one.
    window.opener = null
    window.open('', '_self')
    window.close()
  }
}

/**
 * 下载文件流
 * @param {*} streamData
 * @param {*} name
 * @param {*} timestamp 是否需要在文件名后面自动加上时间戳
 */
export function downloadFileStream(
  streamData,
  name = 'file',
  timestamp = false
) {
  if (timestamp) {
    const ext = name.split('.').pop()
    const realName = name.replace(/\.[^/.]+$/, '')
    const timestamp = moment(new Date()).format('YYYYMMDDHHmm')
    name = `${realName}${timestamp}.${ext}`
  }
  const url = window.URL.createObjectURL(new Blob([streamData]))
  const link = document.createElement('a')
  link.href = url
  link.setAttribute('download', name)
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

/**
 * 下载json
 * @param {*} param0
 */
export async function downloadJson({ data = '', name = '.json' } = {}) {
  const url = window.URL.createObjectURL(new Blob([data]))
  const link = document.createElement('a')
  link.href = url
  link.setAttribute('download', name)
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

/**
 * 应用基础数据导出 文件名生成
 * @param {*} param0
 */
export function genAppDataPrefix({ key = '', ext = '' } = {}) {
  const { appName, appUniqueId: appUnique } = store.getters.APP_INFO
  const time = moment().format('YYYYMMDDHHmmss')
  return `${appName}_${appUnique}_${key}_${time}.${ext}`
}

/**
 * 应用基础数据导出
 * @param {*} param0
 */
export async function exportAppDataFromJson({
  data = '',
  key = '',
  ext = 'json'
} = {}) {
  const name = genAppDataPrefix({
    key,
    ext
  })
  await downloadJson({ data, name })
}

/**
 * url静默下载文件
 * @param {*} url
 * @param {*} name
 */
export async function downloadFileSrc(fileUrl, name) {
  try {
    var response = await fetch(fileUrl)
    if (response.status > 400) {
      Message.info('下载失败')
      return
    }
    var blob = await response.blob()
    var objectUrl = window.URL.createObjectURL(blob)
    var a = document.createElement('a')
    a.download = name || fileUrl
    a.href = objectUrl
    document.body.appendChild(a)
    a.click()
    window.URL.revokeObjectURL(a.href)
    document.body.removeChild(a)
  } catch (error) {
    window.open(fileUrl)
  }
}
/**
 * 复制
 */
export function copy(text) {
  const input = document.createElement('input')
  document.body.appendChild(input)
  input.setAttribute('value', text)
  input.select() // 选中文本
  document.execCommand('copy')
  document.body.removeChild(input)
  Message.success('复制成功')
}

/**
 * 非递归广度优先搜索树
 * @param {*} jsonTree
 * @param {*} callback
 * @param {*} key
 */
export function breadFirstTree(jsonTree, callback, key) {
  if (!jsonTree) return
  let array = []
  if (
    typeof jsonTree === 'object' &&
    jsonTree.constructor === Object.prototype.constructor
  ) {
    array.push(jsonTree)
  } else if (Array.isArray(jsonTree)) {
    array = jsonTree
  } else {
    return
  }

  let stack = []

  // 先将第一层节点放入栈
  for (let i = 0, len = array.length; i < len; i++) {
    stack.push(array[i])
  }

  let jn

  while (stack.length) {
    jn = stack.shift()

    const re = callback(jn, array)
    if (!re) {
      return false
    }
    if (re !== -1 && jn[key] && jn[key].length > 0) {
      stack = stack.concat(jn[key])
    }
  }
}

/**
 * 根据节点id获取完整的树节点数据
 * @param tree
 * @param id
 */
export function getTreeNodeById(tree, id) {
  let treeNode = {}
  if (id) {
    breadFirstTree(
      tree,
      (node) => {
        if (node.id === id) {
          treeNode = node
          return false
        }
        return true
      },
      'children'
    )
  }
  return treeNode
}

/**
 * 生成UUID
 */

export function uuidv4() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = (Math.random() * 16) | 0
    var v = c == 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}

/**
 * 格式化秒
 * @param   int     value   总秒数
 * @return  string  result  格式化后的字符串
 */
export function formatSeconds(value) {
  let theTime = parseInt(value) // 需要转换的时间秒
  let theTime1 = 0 // 分
  let theTime2 = 0 // 小时
  let theTime3 = 0 // 天
  if (theTime >= 60) {
    theTime1 = parseInt(theTime / 60)
    theTime = parseInt(theTime % 60)
    if (theTime1 >= 60) {
      theTime2 = parseInt(theTime1 / 60)
      theTime1 = parseInt(theTime1 % 60)
      if (theTime2 >= 24) {
        // 大于24小时
        theTime3 = parseInt(theTime2 / 24)
        theTime2 = parseInt(theTime2 % 24)
      }
    }
  }
  let result = ''
  if (theTime > 0) {
    result = '' + parseInt(theTime) + '秒'
  }
  if (theTime1 > 0) {
    result = '' + parseInt(theTime1) + '分' + result
  }
  if (theTime2 > 0) {
    result = '' + parseInt(theTime2) + '小时' + result
  }
  if (theTime3 > 0) {
    result = '' + parseInt(theTime3) + '天' + result
  }
  return result
}

// 阿拉伯数字转中文数字
export function noToChinese(num) {
  if (!/^\d*(\.\d*)?$/.test(num)) {
    alert('Number is wrong!')
    return 'Number is wrong!'
  }
  const AA = new Array(
    '零',
    '一',
    '二',
    '三',
    '四',
    '五',
    '六',
    '七',
    '八',
    '九'
  )
  const BB = new Array('', '十', '百', '千', '万', '亿', '点', '')
  const a = ('' + num).replace(/(^0*)/g, '').split('.')
  let k = 0
  let re = ''
  for (var i = a[0].length - 1; i >= 0; i--) {
    switch (k) {
      case 0:
        re = BB[7] + re
        break
      case 4:
        if (!new RegExp('0{4}\\d{' + (a[0].length - i - 1) + '}$').test(a[0])) {
          re = BB[4] + re
        }
        break
      case 8:
        re = BB[5] + re
        BB[7] = BB[5]
        k = 0
        break
    }
    if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0) {
      re = AA[0] + re
    }
    if (a[0].charAt(i) != 0) re = AA[a[0].charAt(i)] + BB[k % 4] + re
    k++
  }
  if (a.length > 1) {
    // 加上小数部分(如果有小数部分)
    re += BB[6]
    for (var i = 0; i < a[1].length; i++) re += AA[a[1].charAt(i)]
  }
  return re
}

/**
 * 判断时间是否有包含关系 period in range or not
 * @param {*} range
 * @param {*} period
 */
export function isTimeContain(range, period) {
  const rangeFrom = range.from
  const rangeTo =
    range.to >= range.from
      ? range.to
      : range.to.replace(/^(\d{2})/, (s) => Number(s) + 24)
  const periodFrom = period.from
  const periodTo =
    period.to >= period.from
      ? period.to
      : period.to.replace(/^(\d{2})/, (s) => Number(s) + 24)
  let bContain = false
  if (periodFrom >= rangeFrom && periodTo <= rangeTo) {
    bContain = true
  } else {
    const periodFromNext = period.from.replace(
      /^(\d{2})/,
      (s) => Number(s) + 24
    )
    const periodToNext = period.to.replace(/^(\d{2})/, (s) => Number(s) + 24)
    if (periodFromNext >= rangeFrom && periodToNext <= rangeTo) {
      bContain = true
    }
  }
  return bContain
}

/**
 * 判断时间是否有交叉关系关系
 * @param {*} range
 * @param {*} period
 */
export function isTimeCross(range, period) {
  const rangeFrom = range.from
  const rangeTo =
    range.to >= range.from
      ? range.to
      : range.to.replace(/^(\d{2})/, (s) => Number(s) + 24)
  const periodFrom = period.from
  const periodTo =
    period.to >= period.from
      ? period.to
      : period.to.replace(/^(\d{2})/, (s) => Number(s) + 24)

  const periodFromNext = period.from.replace(/^(\d{2})/, (s) => Number(s) + 24)
  const periodToNext = period.to.replace(/^(\d{2})/, (s) => Number(s) + 24)
  let bCross = true

  if (
    (periodTo <= rangeFrom || periodFrom >= rangeTo) &&
    (periodToNext <= rangeFrom || periodFromNext >= rangeTo)
  ) {
    bCross = false
  }
  return bCross
}

/**
 * 数据转换为list格式
 * @param {*} data
 * @returns
 */
export function dataToList(data) {
  const type = Object.prototype.toString.call(data)
  if (type === '[object Array]') {
    return data
  } else if (
    type === '[object Object]' &&
    data.data &&
    Object.prototype.toString.call(data.data) === '[object Array]'
  ) {
    return data.data
  } else {
    return []
  }
}


